handle 0-height empty/invisible lines.
authorHavoc Pennington <hp@pobox.com>
Tue, 24 Apr 2001 12:24:35 +0000 (12:24 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Tue, 24 Apr 2001 12:24:35 +0000 (12:24 +0000)
2001-04-21  Havoc Pennington  <hp@pobox.com>

* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
empty/invisible lines.

* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
(gtk_text_iter_set_visible_line_index): new functions to set
indexes excluding invisible text

* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
index

* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
(gtk_text_iter_get_visible_line_offset): new functions to
get indexes excluding invisible text

* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
bunch of extra padding that served no purpose

* gtk/gtkdialog.c: Make all the spacings configurable via style
properties, for chubbiness configuration in themes

* tests/testtext.c: fix path to the immodules.

16 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/gtk/tmpl/gtkrc.sgml
gtk/gtkdialog.c
gtk/gtkmessagedialog.c
gtk/gtktextbuffer.h
gtk/gtktextdisplay.c
gtk/gtktextiter.c
gtk/gtktextiter.h
gtk/gtktextlayout.c
tests/testtext.c

index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 0b32b0f69a05b4650820a9ffe74ccff132b2416f..2759990064e89512c0a50690fd7ecc92e129ea2e 100644 (file)
@@ -1,3 +1,27 @@
+2001-04-21  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
+       empty/invisible lines.
+
+       * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
+       (gtk_text_iter_set_visible_line_index): new functions to set
+       indexes excluding invisible text
+
+       * gtk/gtktextlayout.c (line_display_iter_to_index): get visible 
+       index
+
+       * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
+       (gtk_text_iter_get_visible_line_offset): new functions to 
+       get indexes excluding invisible text
+
+       * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
+       bunch of extra padding that served no purpose
+
+       * gtk/gtkdialog.c: Make all the spacings configurable via style
+       properties, for chubbiness configuration in themes
+
+       * tests/testtext.c: fix path to the immodules.
+       
 Mon Apr 23 18:57:03 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
index 178b40392298c4059e35c7c6e505cd0fa52ed528..4c81682d1736c779823c68b1ab5f88dd380720a9 100644 (file)
@@ -496,6 +496,7 @@ This can later be composited together with other
 #GtkRcStyle structures to form a #GtkStyle.
 </para>
 
+@parent_instance: 
 @name: 
 @bg_pixmap_name: 
 @font_desc: 
index b4af6a7a26d526c11f0e7926527c2b1914ca2c4e..324f781d157f4aa377f04a7f3cc7bc7a876d51bf 100644 (file)
@@ -55,6 +55,8 @@ static void gtk_dialog_get_property      (GObject          *object,
                                           guint             prop_id,
                                           GValue           *value,
                                           GParamSpec       *pspec);
+static void gtk_dialog_style_set         (GtkWidget        *widget,
+                                          GtkStyle         *prev_style);
 
 enum {
   PROP_0,
@@ -111,7 +113,8 @@ gtk_dialog_class_init (GtkDialogClass *class)
   gobject_class->get_property = gtk_dialog_get_property;
   
   widget_class->key_press_event = gtk_dialog_key_press;
-
+  widget_class->style_set = gtk_dialog_style_set;
+  
   g_object_class_install_property (gobject_class,
                                    PROP_HAS_SEPARATOR,
                                    g_param_spec_boolean ("has_separator",
@@ -128,6 +131,59 @@ gtk_dialog_class_init (GtkDialogClass *class)
                     gtk_marshal_NONE__INT,
                    GTK_TYPE_NONE, 1,
                     GTK_TYPE_INT);
+
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("content_area_border",
+                                                             _("Content area border"),
+                                                             _("Width of border around the main dialog area"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             2,
+                                                             G_PARAM_READABLE));
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_int ("button_spacing",
+                                                             _("Button spacing"),
+                                                             _("Spacing between buttons"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             1,
+                                                             G_PARAM_READABLE));
+  
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_int ("action_area_border",
+                                                             _("Action area border"),
+                                                             _("Width of border around the button area at the bottom of the dialog"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             0,
+                                                             G_PARAM_READABLE));
+}
+
+static void
+update_spacings (GtkDialog *dialog)
+{
+  GtkWidget *widget;
+  gint content_area_border;
+  gint button_spacing;
+  gint action_area_border;
+  
+  widget = GTK_WIDGET (dialog);
+
+  gtk_widget_style_get (widget,
+                        "content_area_border",
+                        &content_area_border,
+                        "button_spacing",
+                        &button_spacing,
+                        "action_area_border",
+                        &action_area_border,
+                        NULL);
+
+  gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox),
+                                  content_area_border);
+  gtk_box_set_spacing (GTK_BOX (dialog->action_area),
+                       button_spacing);
+  gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area),
+                                  action_area_border);
 }
 
 static void
@@ -143,8 +199,6 @@ gtk_dialog_init (GtkDialog *dialog)
                       NULL);
   
   dialog->vbox = gtk_vbox_new (FALSE, 0);
-
-  gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 2);
   
   gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
   gtk_widget_show (dialog->vbox);
@@ -152,11 +206,8 @@ gtk_dialog_init (GtkDialog *dialog)
   dialog->action_area = gtk_hbutton_box_new ();
 
   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog->action_area),
-                             GTK_BUTTONBOX_END);
+                             GTK_BUTTONBOX_END);  
 
-  gtk_box_set_spacing (GTK_BOX (dialog->action_area), 5);
-  
-  gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
   gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
                     FALSE, TRUE, 0);
   gtk_widget_show (dialog->action_area);
@@ -252,6 +303,13 @@ gtk_dialog_key_press (GtkWidget   *widget,
   return TRUE;
 }
 
+static void
+gtk_dialog_style_set (GtkWidget *widget,
+                      GtkStyle  *prev_style)
+{
+  update_spacings (GTK_DIALOG (widget));
+}
+
 GtkWidget*
 gtk_dialog_new (void)
 {
@@ -444,7 +502,7 @@ gtk_dialog_add_action_widget  (GtkDialog *dialog,
 
   gtk_box_pack_end (GTK_BOX (dialog->action_area),
                     child,
-                    FALSE, TRUE, 5);  
+                    FALSE, TRUE, 0);  
 }
 
 /**
index 6a74193cf2d3b152b30ae2a5c4945be926df6585..c6a0145a93ce4847badb89f8114b2b8bcc6177c5 100644 (file)
 #include "gtkimage.h"
 #include "gtkstock.h"
 #include "gtkiconfactory.h"
+#include "gtkintl.h"
 
 static void gtk_message_dialog_class_init (GtkMessageDialogClass *klass);
 static void gtk_message_dialog_init       (GtkMessageDialog      *dialog);
+static void gtk_message_dialog_style_set  (GtkWidget             *widget,
+                                           GtkStyle              *prev_style);
 
+static gpointer parent_class;
 
 GtkType
 gtk_message_dialog_get_type (void)
@@ -63,6 +67,22 @@ gtk_message_dialog_get_type (void)
 static void
 gtk_message_dialog_class_init (GtkMessageDialogClass *class)
 {
+  GtkWidgetClass *widget_class;
+
+  widget_class = GTK_WIDGET_CLASS (class);
+
+  parent_class = g_type_class_peek_parent (class);
+  
+  widget_class->style_set = gtk_message_dialog_style_set;
+  
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_int ("message_border",
+                                                             _("Image/label border"),
+                                                             _("Width of border around the label and image in the message dialog"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             8,
+                                                             G_PARAM_READABLE));
 }
 
 static void
@@ -75,19 +95,17 @@ gtk_message_dialog_init (GtkMessageDialog *dialog)
   
   gtk_label_set_line_wrap (GTK_LABEL (dialog->label), TRUE);
 
-  hbox = gtk_hbox_new (FALSE, 10);
+  hbox = gtk_hbox_new (FALSE, 6);
 
-  gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
-  
   gtk_box_pack_start (GTK_BOX (hbox), dialog->image,
-                      FALSE, FALSE, 2);
+                      FALSE, FALSE, 0);
 
   gtk_box_pack_start (GTK_BOX (hbox), dialog->label,
-                      TRUE, TRUE, 2);
+                      TRUE, TRUE, 0);
 
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
                       hbox,
-                      FALSE, FALSE, 10);
+                      FALSE, FALSE, 0);
 
   gtk_widget_show_all (hbox);
 }
@@ -247,3 +265,25 @@ gtk_message_dialog_new (GtkWindow     *parent,
 
   return widget;
 }
+
+static void
+gtk_message_dialog_style_set (GtkWidget *widget,
+                              GtkStyle  *prev_style)
+{
+  GtkWidget *parent;
+  gint border_width = 0;
+
+  parent = GTK_WIDGET (GTK_MESSAGE_DIALOG (widget)->image->parent);
+
+  if (parent)
+    {
+      gtk_widget_style_get (widget, "message_border",
+                            &border_width, NULL);
+      
+      gtk_container_set_border_width (GTK_CONTAINER (parent),
+                                      border_width);
+    }
+
+  if (GTK_WIDGET_CLASS (parent_class)->style_set)
+    (GTK_WIDGET_CLASS (parent_class)->style_set) (widget, prev_style);
+}
index 54f245e8aa563a4cb6d743ac25eed8f753c487fd..b6f801f11994e2e7808675e7dad170df07cb1d96 100644 (file)
@@ -277,7 +277,8 @@ GtkTextTag    *gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
                                            ...);
 
 /* Obtain iterators pointed at various places, then you can move the
-   iterator around using the GtkTextIter operators */
+ * iterator around using the GtkTextIter operators
+ */
 void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
                                               GtkTextIter   *iter,
                                               gint           line_number,
index 17e3f5b5605fa867fca5447b62f3e4f9770b6cb1..0b2c3f78725346b8737341c20333eab3654e44ea 100644 (file)
@@ -739,66 +739,71 @@ gtk_text_layout_draw (GtkTextLayout *layout,
       GtkTextLine *line = tmp_list->data;
 
       line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
-      
-      if (have_selection)
-        {
-          GtkTextIter line_start, line_end;
-          gint byte_count;
 
-          gtk_text_layout_get_iter_at_line (layout,
-                                            &line_start,
-                                            line, 0);
-          byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
+      if (line_display->height > 0)
+        {
+          g_assert (line_display->layout != NULL);
           
-          /* FIXME the -1 assumes a newline I think */
-          gtk_text_layout_get_iter_at_line (layout,
-                                            &line_end,
-                                            line, byte_count - 1);
-
-          if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
-              gtk_text_iter_compare (&selection_end, &line_start) > 0)
+          if (have_selection)
             {
-              if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
-                selection_start_index = gtk_text_iter_get_line_index (&selection_start);
-              else
-                selection_start_index = -1;
+              GtkTextIter line_start, line_end;
+              gint byte_count;
 
-              if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
-                selection_end_index = gtk_text_iter_get_line_index (&selection_end);
-              else
-                selection_end_index = byte_count;
+              gtk_text_layout_get_iter_at_line (layout,
+                                                &line_start,
+                                                line, 0);
+              byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
+          
+              /* FIXME the -1 assumes a newline I think */
+              gtk_text_layout_get_iter_at_line (layout,
+                                                &line_end,
+                                                line, byte_count - 1);
+
+              if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
+                  gtk_text_iter_compare (&selection_end, &line_start) > 0)
+                {
+                  if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
+                    selection_start_index = gtk_text_iter_get_line_index (&selection_start);
+                  else
+                    selection_start_index = -1;
+
+                  if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
+                    selection_end_index = gtk_text_iter_get_line_index (&selection_end);
+                  else
+                    selection_end_index = byte_count;
+                }
             }
-        }
 
-      render_para (drawable, render_state, line_display,
-                   - x_offset,
-                   current_y,
-                   selection_start_index, selection_end_index);
+          render_para (drawable, render_state, line_display,
+                       - x_offset,
+                       current_y,
+                       selection_start_index, selection_end_index);
 
 
-      /* We paint the cursors last, because they overlap another chunk
+          /* We paint the cursors last, because they overlap another chunk
          and need to appear on top. */
 
-      cursor_list = line_display->cursors;
-      while (cursor_list)
-        {
-          GtkTextCursorDisplay *cursor = cursor_list->data;
-          GdkGC *gc;
-
-          if (cursor->is_strong)
-            gc = widget->style->base_gc[GTK_STATE_SELECTED];
-          else
-            gc = widget->style->text_gc[GTK_STATE_NORMAL];
+          cursor_list = line_display->cursors;
+          while (cursor_list)
+            {
+              GtkTextCursorDisplay *cursor = cursor_list->data;
+              GdkGC *gc;
 
-          gdk_draw_line (drawable, gc,
-                         line_display->x_offset + cursor->x - x_offset,
-                         current_y + line_display->top_margin + cursor->y,
-                         line_display->x_offset + cursor->x - x_offset,
-                         current_y + line_display->top_margin + cursor->y + cursor->height - 1);
+              if (cursor->is_strong)
+                gc = widget->style->base_gc[GTK_STATE_SELECTED];
+              else
+                gc = widget->style->text_gc[GTK_STATE_NORMAL];
 
-          cursor_list = cursor_list->next;
-        }
+              gdk_draw_line (drawable, gc,
+                             line_display->x_offset + cursor->x - x_offset,
+                             current_y + line_display->top_margin + cursor->y,
+                             line_display->x_offset + cursor->x - x_offset,
+                             current_y + line_display->top_margin + cursor->y + cursor->height - 1);
 
+              cursor_list = cursor_list->next;
+            }
+        } /* line_display->height > 0 */
+          
       current_y += line_display->height;
       gtk_text_layout_free_line_display (layout, line_display);
       render_state->last_appearance = NULL;
index 73a51ed368949fc164d847126b90fc3bdb271fa9..241529d389564dc10d6b74250ad82fee9cfc98ae 100644 (file)
@@ -650,7 +650,6 @@ gtk_text_iter_get_line (const GtkTextIter *iter)
 gint
 gtk_text_iter_get_line_offset (const GtkTextIter *iter)
 {
-
   GtkTextRealIter *real;
 
   g_return_val_if_fail (iter != NULL, 0);
@@ -683,7 +682,7 @@ gint
 gtk_text_iter_get_line_index (const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
-
+  
   g_return_val_if_fail (iter != NULL, 0);
 
   real = gtk_text_iter_make_surreal (iter);
@@ -698,6 +697,108 @@ gtk_text_iter_get_line_index (const GtkTextIter *iter)
   return real->line_byte_offset;
 }
 
+gint
+gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter)
+{
+  GtkTextRealIter *real;
+  gint vis_offset;
+  GtkTextLineSegment *seg;
+  GtkTextIter pos;
+  
+  g_return_val_if_fail (iter != NULL, 0);
+
+  real = gtk_text_iter_make_real (iter);
+
+  if (real == NULL)
+    return 0;
+
+  ensure_char_offsets (real);
+
+  check_invariants (iter);
+
+  vis_offset = real->line_char_offset;
+
+  _gtk_text_btree_get_iter_at_line (real->tree,
+                                    &pos,
+                                    real->line,
+                                    0);
+
+  seg = _gtk_text_iter_get_indexable_segment (&pos);
+
+  while (seg != real->segment)
+    {
+      /* This is a pretty expensive call, making the
+       * whole function pretty lame; we could keep track
+       * of current invisibility state by looking at toggle
+       * segments as we loop, and then call this function
+       * only once per line, in order to speed up the loop
+       * quite a lot.
+       */
+      if (_gtk_text_btree_char_is_invisible (&pos))
+        vis_offset -= seg->char_count;
+
+      _gtk_text_iter_forward_indexable_segment (&pos);
+
+      seg = _gtk_text_iter_get_indexable_segment (&pos);
+    }
+
+  if (_gtk_text_btree_char_is_invisible (&pos))
+    vis_offset -= real->segment_char_offset;
+  
+  return vis_offset;
+}
+
+gint
+gtk_text_iter_get_visible_line_index (const GtkTextIter *iter)
+{
+  GtkTextRealIter *real;
+  gint vis_offset;
+  GtkTextLineSegment *seg;
+  GtkTextIter pos;
+  
+  g_return_val_if_fail (iter != NULL, 0);
+
+  real = gtk_text_iter_make_real (iter);
+
+  if (real == NULL)
+    return 0;
+
+  ensure_char_offsets (real);
+
+  check_invariants (iter);
+
+  vis_offset = real->line_byte_offset;
+
+  _gtk_text_btree_get_iter_at_line (real->tree,
+                                    &pos,
+                                    real->line,
+                                    0);
+
+  seg = _gtk_text_iter_get_indexable_segment (&pos);
+
+  while (seg != real->segment)
+    {
+      /* This is a pretty expensive call, making the
+       * whole function pretty lame; we could keep track
+       * of current invisibility state by looking at toggle
+       * segments as we loop, and then call this function
+       * only once per line, in order to speed up the loop
+       * quite a lot.
+       */
+      if (_gtk_text_btree_char_is_invisible (&pos))
+        vis_offset -= seg->byte_count;
+
+      _gtk_text_iter_forward_indexable_segment (&pos);
+
+      seg = _gtk_text_iter_get_indexable_segment (&pos);
+    }
+
+  if (_gtk_text_btree_char_is_invisible (&pos))
+    vis_offset -= real->segment_byte_offset;
+  
+  return vis_offset;
+}
+
 /*
  * Dereferencing
  */
@@ -3276,6 +3377,97 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
   check_invariants (iter);
 }
 
+
+/**
+ * gtk_text_iter_set_visible_line_offset:
+ * @iter: a #GtkTextIter
+ * @char_on_line: a character offset
+ * 
+ * Like gtk_text_iter_set_line_offset(), but the offset is in visible
+ * characters, i.e. text with a tag making it invisible is not
+ * counted in the offset.
+ **/
+void
+gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
+                                       gint         char_on_line)
+{
+  gint chars_seen = 0;
+  GtkTextIter pos;
+
+  g_return_if_fail (iter != NULL);
+  
+  pos = *iter;
+
+  /* For now we use a ludicrously slow implementation */
+  while (chars_seen < char_on_line)
+    {
+      if (!_gtk_text_btree_char_is_invisible (&pos))
+        ++chars_seen;
+
+      if (!gtk_text_iter_forward_char (&pos))
+        break;
+
+      if (chars_seen == char_on_line)
+        break;
+    }
+  
+  if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
+    *iter = pos;
+  else
+    gtk_text_iter_forward_line (iter);
+}
+
+static gint
+bytes_in_char (GtkTextIter *iter)
+{
+  return g_unichar_to_utf8 (gtk_text_iter_get_char (iter), NULL);
+}
+
+/**
+ * gtk_text_iter_set_visible_line_index:
+ * @iter: a #GtkTextIter
+ * @byte_on_line: a byte index
+ * 
+ * Like gtk_text_iter_set_line_index(), but the index is in visible
+ * bytes, i.e. text with a tag making it invisible is not counted
+ * in the index.
+ **/
+void
+gtk_text_iter_set_visible_line_index  (GtkTextIter *iter,
+                                       gint         byte_on_line)
+{
+  gint bytes_seen = 0;
+  GtkTextIter pos;
+
+  g_return_if_fail (iter != NULL);
+  
+  pos = *iter;
+
+  /* For now we use a ludicrously slow implementation */
+  while (bytes_seen < byte_on_line)
+    {
+      if (!_gtk_text_btree_char_is_invisible (&pos))
+        bytes_seen += bytes_in_char (&pos);
+
+      if (!gtk_text_iter_forward_char (&pos))
+        break;
+
+      if (bytes_seen >= byte_on_line)
+        break;
+    }
+
+  if (bytes_seen > byte_on_line)
+    g_warning ("%s: Incorrect visible byte index %d falls in the middle of a UTF-8 "
+               "character; this will crash the text buffer. "
+               "Byte indexes must refer to the start of a character.",
+               G_STRLOC, byte_on_line);
+  
+  if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
+    *iter = pos;
+  else
+    gtk_text_iter_forward_line (iter);
+}
+
 /**
  * gtk_text_iter_set_line:
  * @iter: a #GtkTextIter
index 9b25a8be49419179edaaa1f97493dbec69aa3b86..00285e287b9ba09bef5b8b9b4392402520f50100 100644 (file)
@@ -78,6 +78,9 @@ gint gtk_text_iter_get_line        (const GtkTextIter *iter);
 gint gtk_text_iter_get_line_offset (const GtkTextIter *iter);
 gint gtk_text_iter_get_line_index  (const GtkTextIter *iter);
 
+gint gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter);
+gint gtk_text_iter_get_visible_line_index (const GtkTextIter *iter);
+
 
 /*
  * "Dereference" operators
@@ -197,6 +200,10 @@ void     gtk_text_iter_set_line_index     (GtkTextIter *iter,
 void     gtk_text_iter_forward_to_end     (GtkTextIter *iter);
 gboolean gtk_text_iter_forward_to_line_end (GtkTextIter *iter);
 
+void     gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
+                                                gint         char_on_line);
+void     gtk_text_iter_set_visible_line_index  (GtkTextIter *iter,
+                                                gint         byte_on_line);
 
 /* returns TRUE if a toggle was found; NULL for the tag pointer
  * means "any tag toggle", otherwise the next toggle of the
index dad06d319deab3fd6f7cd6398e02f6c33543d188..ec61bb250a2f74991815c1c0c456ebbe12f9e104 100644 (file)
@@ -994,14 +994,16 @@ totally_invisible_line (GtkTextLayout *layout,
   int bytes = 0;
 
   /* If we have a cached style, then we know it does actually apply
-     and we can just see if it is invisible. */
+   * and we can just see if it is invisible.
+   */
   if (layout->one_style_cache &&
       !layout->one_style_cache->invisible)
     return FALSE;
   /* Without the cache, we check if the first char is visible, if so
-     we are partially visible.  Note that we have to check this since
-     we don't know the current invisible/noninvisible toggle state; this
-     function can use the whole btree to get it right. */
+   * we are partially visible.  Note that we have to check this since
+   * we don't know the current invisible/noninvisible toggle state; this
+   * function can use the whole btree to get it right.
+   */
   else
     {
       _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
@@ -1020,10 +1022,11 @@ totally_invisible_line (GtkTextLayout *layout,
         bytes += seg->byte_count;
 
       /* Note that these two tests can cause us to bail out
-         when we shouldn't, because a higher-priority tag
-         may override these settings. However the important
-         thing is to only invisible really-invisible lines, rather
-         than to invisible all really-invisible lines. */
+       * when we shouldn't, because a higher-priority tag
+       * may override these settings. However the important
+       * thing is to only invisible really-invisible lines, rather
+       * than to invisible all really-invisible lines.
+       */
 
       else if (seg->type == &gtk_text_toggle_on_type)
         {
@@ -1478,8 +1481,6 @@ allocate_child_widgets (GtkTextLayout      *text_layout,
               pango_layout_iter_get_run_extents (iter,
                                                  NULL,
                                                  &extents);
-
-              g_print ("extents at %d,%d\n", extents.x, extents.y);
               
               g_signal_emit (G_OBJECT (text_layout),
                              signals[ALLOCATE_CHILD],
@@ -1593,7 +1594,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
   GtkTextAttributes *style;
   gchar *text;
   PangoAttrList *attrs;
-  gint byte_count, layout_byte_offset, layout_only_bytes;
+  gint text_allocated, layout_byte_offset, buffer_byte_offset;
   gdouble align;
   PangoRectangle extents;
   gboolean para_values_set = FALSE;
@@ -1635,14 +1636,14 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
 
   /* Allocate space for flat text for buffer
    */
-  byte_count = _gtk_text_line_byte_count (line);
-  text = g_malloc (byte_count);
+  text_allocated = _gtk_text_line_byte_count (line);
+  text = g_malloc (text_allocated);
 
   attrs = pango_attr_list_new ();
 
   /* Iterate over segments, creating display chunks for them. */
-  layout_byte_offset = 0; /* current length of layout text (includes preedit) */
-  layout_only_bytes = 0; /* bytes in layout_byte_offset not in buffer */
+  layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
+  buffer_byte_offset = 0; /* position in the buffer line */
   seg = _gtk_text_iter_get_any_segment (&iter);
   while (seg != NULL)
     {
@@ -1653,7 +1654,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
         {
           _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                             &iter, line,
-                                            layout_byte_offset - layout_only_bytes);
+                                            buffer_byte_offset);
           style = get_style (layout, &iter);
 
           /* We have to delay setting the paragraph values until we
@@ -1692,6 +1693,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                         {
                           memcpy (text + layout_byte_offset, seg->body.chars, seg->byte_count);
                           layout_byte_offset += seg->byte_count;
+                          buffer_byte_offset += seg->byte_count;
                           bytes += seg->byte_count;
                         }
                      else if (seg->type == &gtk_text_right_mark_type ||
@@ -1739,6 +1741,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                   memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
+                  buffer_byte_offset += seg->byte_count;
                 }
               else if (seg->type == &gtk_text_child_type)
                 {
@@ -1753,11 +1756,19 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                   memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
+                  buffer_byte_offset += seg->byte_count;
                 }
               else
                 {
+                  /* We don't know this segment type */
                   g_assert_not_reached ();
                 }
+              
+            } /* if (segment was visible) */
+          else
+            {
+              /* Invisible segment */
+              buffer_byte_offset += seg->byte_count;
             }
 
           release_style (layout, style);
@@ -1787,8 +1798,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
              
              if (layout->preedit_len > 0)
                {
-                 byte_count += layout->preedit_len;
-                 text = g_realloc (text, byte_count);
+                 text_allocated += layout->preedit_len;
+                 text = g_realloc (text, text_allocated);
 
                  style = get_style (layout, &iter);
                  add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
@@ -1796,7 +1807,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                   
                  memcpy (text + layout_byte_offset, layout->preedit_string, layout->preedit_len);
                  layout_byte_offset += layout->preedit_len;
-                  layout_only_bytes += layout->preedit_len;
+                  /* DO NOT increment the buffer byte offset for preedit */
                   
                  cursor_offset = layout->preedit_cursor - layout->preedit_len;
                }
@@ -1825,8 +1836,6 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
       set_para_values (layout, style, display, &align);
       release_style (layout, style);
     }
-
-  g_assert (layout_byte_offset == byte_count);
   
   /* Pango doesn't want the trailing paragraph delimiters */
 
@@ -1897,7 +1906,8 @@ gtk_text_layout_free_line_display (GtkTextLayout      *layout,
 {
   if (display != layout->one_display_cache)
     {
-      g_object_unref (G_OBJECT (display->layout));
+      if (display->layout)
+        g_object_unref (G_OBJECT (display->layout));
 
       if (display->cursors)
         {
@@ -1911,7 +1921,7 @@ gtk_text_layout_free_line_display (GtkTextLayout      *layout,
 }
 
 /* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
- * taking into account the preedit string, if necessary.
+ * taking into account the preedit string and invisible text if necessary.
  */
 static gint
 line_display_iter_to_index (GtkTextLayout      *layout,
@@ -1922,8 +1932,8 @@ line_display_iter_to_index (GtkTextLayout      *layout,
 
   g_return_val_if_fail (_gtk_text_iter_get_text_line (iter) == display->line, 0);
 
-  index = gtk_text_iter_get_line_index (iter);
-
+  index = gtk_text_iter_get_visible_line_index (iter);
+  
   if (index >= display->insert_index)
     index += layout->preedit_len;
 
@@ -1937,8 +1947,6 @@ line_display_index_to_iter (GtkTextLayout      *layout,
                            gint                index,
                            gint                trailing)
 {
-  gint line_len;
-  
   if (index >= display->insert_index + layout->preedit_len)
     index -= layout->preedit_len;
   else if (index > display->insert_index)
@@ -1946,27 +1954,24 @@ line_display_index_to_iter (GtkTextLayout      *layout,
       index = display->insert_index;
       trailing = 0;
     }
-  
-  line_len = _gtk_text_line_byte_count (display->line);
-  g_assert (index <= line_len);
 
-  if (index < line_len)
-    _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                      iter, display->line, index);
-  else
+  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                    iter, display->line, 0);
+
+  gtk_text_iter_set_visible_line_index (iter, index);
+  
+  if (_gtk_text_iter_get_text_line (iter) != display->line)
     {
       /* Clamp to end of line - really this clamping should have been done
        * before here, maybe in Pango, this is a broken band-aid I think
        */
-      g_assert (index == line_len);
-      
       _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                         iter, display->line, 0);
 
       if (!gtk_text_iter_ends_line (iter))
         gtk_text_iter_forward_to_line_end (iter);
     }
-
+  
   /* FIXME should this be cursor positions? */
   gtk_text_iter_forward_chars (iter, trailing);
 }
@@ -2414,7 +2419,7 @@ gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
 }
 
 /**
- * gtk_text_layout_move_iter_to_next_line:
+ * gtk_text_layout_move_iter_to_previous_line:
  * @layout: a #GtkLayout
  * @iter:   a #GtkTextIter
  *
@@ -2439,9 +2444,10 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
   orig = *iter;
   
   line = _gtk_text_iter_get_text_line (iter);
-  display = gtk_text_layout_get_line_display (layout, line, FALSE);
+  display = gtk_text_layout_get_line_display (layout, line, FALSE);  
   line_byte = line_display_iter_to_index (layout, display, iter);
 
+  /* FIXME can't use layout until we check display->height > 0) */
   tmp_list = pango_layout_get_lines (display->layout);
   layout_line = tmp_list->data;
 
@@ -2449,6 +2455,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
     {
       GtkTextLine *prev_line = _gtk_text_line_previous (line);
 
+      /* FIXME keep going back while display->height == 0 */
+      
       if (prev_line)
         {
           gtk_text_layout_free_line_display (layout, display);
index badbaf17a7df91c55da1bdbf19504ccdeb6c6ffe..73c7231f641410b7392fb93bbd36bb19b9ba0cfd 100644 (file)
@@ -2236,7 +2236,7 @@ test_init ()
   if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
     {
       putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
-      putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+      putenv ("GTK_IM_MODULE_FILE=../gtk/gtk.immodules");
     }
 }